package myJs.user.workflow.featureSelection.plsda

import com.softwaremill.quicklens._
import myJs.Implicits._
import myJs.api.Api
import myJs.cps.{InputCp, RSelectMulCp, SelectCp, ToggleCp}
import myJs.myPkg.reactHookForm._
import myJs.tool.Tool
import myJs.tool.Tool._
import myJs.user.workflow.featureSelection.{FeatureSelection, FileSelectCp}
import shared.Pojo.MetDataKind
import shared.pojo.MissionTool.IsPaired
import shared.pojo.Pojo
import shared.pojo.WorkflowMission._

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._

import scala.scalajs.js.JSON

import japgolly.scalajs.react.vdom.all._
import japgolly.scalajs.react._
import japgolly.scalajs.react.React.Fragment
import japgolly.scalajs.react.util.EffectCatsEffect._
import myJs.myPkg.Hooks._
import cats.effect._
import myJs.Implicits._

/** Created by yz on 3/11/2020
  */
object PlsdaCp {

  case class Props(
      curI: Int,
      data: EachPlsdaData,
      dataChange: EachPlsdaData => SyncIO[Unit],
      dataModifyF: (EachPlsdaData => EachPlsdaData) => SyncIO[Unit],
      extraData: ExtraData,
      extraDataChange: ExtraData => SyncIO[Unit],
      fsData: FsData
  ){
    @inline def render: VdomElement = {
      Component(this)
    }
  }

  val Component = ScalaFnComponent[Props] { props =>
    val curTool = Plsda
    val namePrefix = s"plsda.${props.curI}"
    val (showIsPaired, setShowIsPaired) = useState(false)

    object FTool {

      def scaleMethodChange = (v: String) => {
        val newData = props.data.modify(_.scaleMethod).setTo(v)
        props.dataChange(newData)
      }

      def isPairedChange = (v: Boolean) => {
        val newData = props.data.modify(_.isPaired).setTo(v)
        props.dataChange(newData)
      }

      def vipChange = (v: String) => {
        val newData = props.data.modify(_.vip).setTo(v)
        props.dataChange(newData)
      }
      def groupsModifyF = (v: List[String]) => {
        val newData = modifyLens[EachPlsdaData](_.groups).setTo(v)
        props.dataModifyF(newData)
      }

    }
    val formState = ReactHookForm.useFormState(options =
      UseFormStateOptions(
        name = namePrefix
      )
    )
    useEffect(
      SyncIO{
        Tool.refreshNodeColor(props.data.nodeId, formState, namePrefix)
      },
      List(formState)
    )

    useEffect(
     {
        val request =
          IsPaired.Request(file = props.fsData.file, groupFile = props.fsData.groupFile, groups = props.data.groups)
        Api.missionTool.isPaired(request).flatMapSync { response =>
          setShowIsPaired(response)
        }
      },
      List(props.data.groups)
    )

    val dataMatrixGroups = props.fsData.dataMatrix.groups
    useEffect(
      {
        FTool.groupsModifyF(dataMatrixGroups)
      },
      List(dataMatrixGroups)
    )

    val data = props.data
    val allGroupsMap = dataMatrixGroups.optionMap

    div(
      RSelectMulCp.Props(
        value = props.data.groups,
        label = messages("groups"),
        name = s"${namePrefix}.groups",
        optionMap = allGroupsMap,
        onChange = FTool.groupsModifyF
      ).render,
      SelectCp.Props(
        value = props.data.scaleMethod,
        label = messages("scaleMethod"),
        name = s"${namePrefix}.scaleMethod",
        optionMap = scaleMethodMap,
        onChange = FTool.scaleMethodChange
      ).render,
      ToggleCp.Props(
        value = data.isPaired,
        label = messages("paired"),
        name = s"${namePrefix}.isPaired",
        valueChange = FTool.isPairedChange,
        show = (showIsPaired)
      ).render,
      InputCp.Props(
        value = data.vip,
        show = true,
        label = messages("vipCutoff"),
        name = s"${namePrefix}.vip",
        onChange = FTool.vipChange,
        questionInfo = messages("oplsdaVipInfo")
      ).render
    )

  }

}
